package org.weasel.views;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.DrillDownAdapter;
import org.eclipse.ui.part.ViewPart;
import org.weasel.business.Developer;
import org.weasel.controllers.DeveloperViewController;


public class DeveloperView extends ViewPart {

	public static final String ID = "org.weasel.views.DeveloperView"; // TODO Needs to be whatever is mentioned in plugin.xml
	private TableViewer viewer;
	@SuppressWarnings("unused")
	private DrillDownAdapter drillDownAdapter;
	private DeveloperViewController controller;
	
	//actions
	private Action deleteAction;  //  @jve:decl-index=0:
	private Action syncAction;  //  @jve:decl-index=0:
	private Action createDeveloperAction;  //  @jve:decl-index=0:
	private Action doubleClickAction;  //  @jve:decl-index=0:

	/**
	 * The content provider class is responsible for providing objects to the
	 * view. It can wrap existing objects in adapters or simply return objects
	 * as-is. These objects may be sensitive to the current input of the view,
	 * or ignore it and always show the same content (like Task List, for
	 * example).
	 */
	class ViewContentProvider implements IStructuredContentProvider {
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}

		public void dispose() {
		}

		public Object[] getElements(Object parent) {
			Developer[] developer = null;
			if(parent.equals(getViewSite())){
				ArrayList<Developer> developers = controller.displayDeveloperViewContent();
				developer = new Developer[developers.size()];
				for(int i=0; i<developers.size(); i++){
					developer[i] = developers.get(i);
				}
			}
			return developer;
		}
	}

	class ViewLabelProvider extends LabelProvider implements
			ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return ((Developer)obj).getName();
		}

		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}

		public Image getImage(Object obj) {
			return new Image(Display.getCurrent(), getClass().getResourceAsStream("/icons/user.gif"));
		}
	}

	class NameSorter extends ViewerSorter {
		public int compare(Viewer viewer, Object o1, Object o2){
			Developer d1 = (Developer)o1;
			Developer d2 = (Developer)o2;
			return collator.compare(d1.getName(), d2.getName());
		}
	}
	
	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		makeActions();
		hookContextMenu();
		hookDoubleClickAction();
		contributeToActionBars();
		
		controller = DeveloperViewController.instance();
		controller.setViewer(viewer);
		viewer.setInput(getViewSite());
		
		//the developers are loaded in the ViewContentProvider
	}
	
	private void makeActions() {
		doubleClickAction = new Action() {
			@Override
			public void run() {
				controller.executeDoubleClick();
			}
		};
		
		deleteAction = new Action() {
			@Override
			public void run() {
				controller.deleteDeveloper();
			}
		};
		
		deleteAction.setText("delete");
		try {
			deleteAction.setImageDescriptor(ImageDescriptor.createFromURL(new URL("file:icons/delete.gif")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		syncAction = new Action() {
			@Override
			public void run() {
				viewer.refresh();
			}
		};
		syncAction.setText("refresh");
		try {
			syncAction.setImageDescriptor(ImageDescriptor.createFromURL(new URL("file:icons/sync.gif")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		createDeveloperAction = new Action() {
			@Override
			public void run() {
//				treeController = TreeController.instance();
//				treeController.showDeveloperWizard();
				controller.showDeveloperWizard();
			}
		};
		createDeveloperAction.setText("Create a new Developer");
		createDeveloperAction.setToolTipText("Click to create a new developer.");
		try {
			createDeveloperAction.setImageDescriptor(ImageDescriptor.createFromURL(new URL("file:icons/add_developer.gif")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				DeveloperView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(menuMgr, viewer);
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillContextMenu(IMenuManager manager) {
		manager.add(deleteAction);
		// Other plug-ins can contribute there actions here
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}
	
	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(syncAction);
		manager.add(createDeveloperAction);
		manager.add(deleteAction);
	}
	
	
	private void hookDoubleClickAction() {
		viewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				doubleClickAction.run();
			}
		});
	}
	
	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}

}  //  @jve:decl-index=0:visual-constraint="10,10,442,273"
